#ifndef VSANIMSEQUENCE_H
#define VSANIMSEQUENCE_H
#include "VSObject.h"
#include "VSVector3.h"
#include "VSQuat.h"
#include "VSMatrix3X3W.h"
#include "VSName.h"
#include "VSController.h"
#include "VSResource.h"
namespace VSEngine2
{
	class VSStream;
	class VSGRAPHIC_API VSKeyTimeInfo
	{
	public:
		VSKeyTimeInfo(){};
		~VSKeyTimeInfo(){};
		float m_dKeyTime;
	};
	class VSGRAPHIC_API VSKeyTimeVector : public VSKeyTimeInfo
	{
	public:
		VSKeyTimeVector(){};
		~VSKeyTimeVector(){};
		VSVector3 m_Vector;
	};
	class VSGRAPHIC_API VSKeyTimeReal	:public VSKeyTimeInfo
	{
	public:
		VSKeyTimeReal(){}
		~VSKeyTimeReal(){}
		VSREAL	m_Real;
	};
	class VSGRAPHIC_API VSKeyTimeQuaternion : public VSKeyTimeInfo
	{
	public:
		VSKeyTimeQuaternion(){};
		~VSKeyTimeQuaternion(){};	
		VSQuat m_Quat;

	};

	class VSGRAPHIC_API VSBoneWeight : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSBoneWeight();
		VSBoneWeight();
	public:
		VSUsedName	m_cName;
		VSREAL		m_fWeight;	
	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);

	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);

	};
	typedef VSPointer<VSBoneWeight> VSBoneWeightPtr;
	class VSGRAPHIC_API VSBoneRefPos : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSBoneRefPos();
		VSBoneRefPos();
		VSVector3			m_Translation;
		VSVector3			m_Scale;
		VSQuat				m_Rotator;
		VSUsedName			m_cName;
	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);

	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);
	};
	typedef VSPointer<VSBoneRefPos> VSBoneRefPosPtr;

	class VSGRAPHIC_API VSBoneKey : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSBoneKey();

	public:
		VSBoneKey();
		VSArray<VSKeyTimeVector>			m_TranslationArray;
		VSArray<VSKeyTimeVector>			m_ScaleArray;
		VSArray<VSKeyTimeQuaternion>		m_RotatorArray;
		VSUsedName							m_cName;
	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);

	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);
	};
 	typedef VSPointer<VSBoneKey> VSBoneKeyPtr;

	class VSGRAPHIC_API VSWeightSet : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSWeightSet();
		VSWeightSet();
	protected:
		VSArray<VSBoneWeightPtr> m_BoneWeightArray;
	public:
		VSUsedName m_cName;

		void AddBoneWeight(VSBoneWeight * pBoneWeight);
		VSBoneWeight * GetBoneWeight(const VSUsedName & BoneWeightName)const;
		VSBoneWeight * GetBoneWeight(unsigned int i)const;
		inline unsigned int GetBoneWeightNum()const
		{
			return m_BoneWeightArray.GetNum();
		}
	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);
		virtual bool Link(VSStream & rStream);

		virtual bool Register(VSStream & rStream)const;
	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);

	};
	typedef VSPointer<VSWeightSet> VSWeightSetPtr;

	class VSGRAPHIC_API VSRefPos : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSRefPos();
		VSRefPos();
	protected:
		VSArray<VSBoneRefPosPtr> m_BoneRefPosArray;
	public:
		VSUsedName m_cName;

		void AddBoneRefPos(VSBoneRefPos * pBoneRefPos);
		VSBoneRefPos * GetBoneRefPos(const VSUsedName & BoneRefPosName)const;
		VSBoneRefPos * GetBoneRefPos(unsigned int i)const;
		inline unsigned int GetBoneRefPosNum()const
		{
			return m_BoneRefPosArray.GetNum();
		}
	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);
		virtual bool Link(VSStream & rStream);

		virtual bool Register(VSStream & rStream)const;
	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);

	};
	typedef VSPointer<VSRefPos> VSRefPosPtr;

	class VSGRAPHIC_API VSAnim : public VSObject
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSAnim();

	public:
		VSAnim();
	protected:
		VSArray<VSBoneKeyPtr> m_pBoneKeyArray;
		VSREAL m_fLength;
	public:
		void ComputeAnimLength();
		inline VSREAL GetAnimLength()const
		{
			return m_fLength;
		}
		void AddBoneKey(VSBoneKey * pBoneKey);
		VSBoneKey * GetBoneKey(const VSUsedName & AnimName)const;
		VSBoneKey * GetBoneKey(unsigned int uiIndex)const;
		inline unsigned int GetBoneKeyNum()const
		{
			return m_pBoneKeyArray.GetNum();
		}
		VSUsedName m_cName;

		VSVector3 GetTranslation(const VSUsedName & UseName,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSVector3 GetScale(const VSUsedName & UseName,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSQuat	  GetQuat(const VSUsedName & UseName,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSMatrix3X3W GetMat(const VSUsedName & UseName,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;


		VSVector3 GetTranslation(unsigned int i,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSVector3 GetScale(unsigned int i,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSQuat	  GetQuat(unsigned int i,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;
		VSMatrix3X3W GetMat(unsigned int i,VSREAL fTime,unsigned int uiRepeatType = VSController::RT_CLAMP)const;

	public:
		static bool RegisterMainFactory();
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);
		virtual bool Link(VSStream & rStream);

		virtual bool Register(VSStream & rStream)const;
	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);
	};
	typedef VSPointer<VSAnim> VSAnimPtr;

	class VSGRAPHIC_API VSAdditiveAnim : public VSAnim
	{
		//RTTI
		DECLARE_RTTI;
		//PRIORITY
		
	public:
		virtual ~VSAdditiveAnim();
		VSAdditiveAnim();
	public:
		static bool RegisterMainFactory();
	private:
		static bool InitialClassFactory();	
		static VSObject * FactoryFunc();
		static bool ms_bRegisterMainFactory;
		
	};
	class VSGRAPHIC_API VSAnimSet : public VSObject,public VSResource
	{
		//RTTI
		DECLARE_RTTI;

		DECLARE_INITIAL
	public:
		virtual ~VSAnimSet();
	public:
		VSAnimSet();
	protected:
		VSArray<VSAnimPtr> m_pAnimArray;
		VSArray<VSRefPosPtr> m_pRefPosArray;
		VSArray<VSWeightSetPtr> m_pWeightSet;
		static VSPointer<VSAnimSet> Default;
 	public:
		virtual unsigned int GetResourceType()const
		{

			return RT_ANIMSET;
		}
		void AddAnim(VSAnim * pAnim);
		VSAnim * GetAnim(const VSUsedName & AnimName)const;
		VSAnim * GetAnim(unsigned int i)const;
		inline unsigned int GetAnimNum()const
		{
			return m_pAnimArray.GetNum();
		}
		void AddRefPos(VSRefPos * pRefPos);
		VSRefPos * GetRefPos(const VSUsedName & RefPosName)const;
		VSRefPos * GetRefPos(unsigned int i)const;
		inline unsigned int GetRefPos()const
		{
			return m_pRefPosArray.GetNum();
		}

		void AddWeightSet(VSWeightSet * pWeightSet);
		VSWeightSet * GetWeightSet(const VSUsedName & WeightSetName)const;
		VSWeightSet * GetWeightSet(unsigned int i)const;
		inline unsigned int GetWeightSet()const
		{
			return m_pWeightSet.GetNum();
		}

		bool LoadVSAction(const TCHAR *pFileName);
		bool LoadVSRefPos(const TCHAR *pFileName);
		bool LoadVSWeightSet(const TCHAR *pFileName);

		bool AddNewAdditiveAnim(const VSUsedName & SourceAnimName,const VSUsedName & RefPosName);
		
		bool AddNewAdditiveAnim(const VSUsedName & SourceAnimName,
			const VSUsedName & TargetAnimName,bool bUseSourceLength = true);

		bool AddNewAdditiveAnim(const VSUsedName & SourceAnimName,const VSUsedName & TargetAnimName,
								float fTargetTime = 0.0f);
	public:
		static bool ms_bIsEnableASYNLoader;
		static bool ms_bIsEnableGC;
		static const VSAnimSet *GetDefalut()
		{
			return Default;
		}
		virtual unsigned int DiskUse()const;

		virtual bool Save(VSStream & rStream,unsigned int &iSaveUse)const;
		virtual bool Load(VSStream & rStream,unsigned int &iSaveUse);
		virtual bool Link(VSStream & rStream);

		virtual bool Register(VSStream & rStream)const;
	public:
		virtual bool Clone(const VSObject *pObject,unsigned int uiType);
		
		
	};
	DECLARE_Ptr(VSAnimSet);
	VSTYPE_MARCO(VSAnimSet);
	
}
#endif